Theming: Customizing plots

Elizabeth King
Kevin Middleton

What can you customize?

(Nearly) everything.

Blank slate

There is a ggplot here:

ggplot() +
  theme_void()

gg-this and gg-that

  • Lots of packages have plotting functionality built on top of ggplot
  • Not all play nicely with regular ggplot theme elements
    • Can’t + elements, limited ability to modify theme() elements, etc.
    • Your mileage may vary

Scales

scale_ handles changing how aesthetics are represented in plots

  • scale_x_
  • scale_y_
  • scale_color_
  • scale_fill_
  • scale_shape_
  • etc.

Types of scales

scale_aesthetic_type where type is

  • continuous
  • discrete
  • manual
  • date, time, datetime
  • etc.

Different aesthetics have different scale types available

  • RStudio tab completion is your friend here: scale_x-Tab

scale_x_ and scale_y_

Most commonly:

  • scale_{xy}_continuous: Continuous
  • scale_{xy}_discrete: Categorical
  • scale_{xy}_log10: log10 transformation
  • scale_{xy}_sqrt: Square-root transformation
  • scale_{xy}_reverse: Reverse the axis

Electric fish diversity and tributaries

Species abundance of electric fish upstream and downstream of the entrance of a tributary in the Amazon basin.

Tributary n_Upstream n_Downstream
Coari 5 7
Ica 14 19
Japura 8 8
Jutai 11 18
Madeira 29 30
Manacapuru 5 6
Negro 23 24
Purus 10 16
Tapajos 16 20
Tocantins 10 12
Trombetas 19 16
Xingu 25 21

Electric fish visualization

  1. Bar plot of n_Upstream and n_Downstream diversity by Tributary
  2. Scatter plot of n_Upstream vs. n_Downstream

Bar plot

EF_bar <- EF |> 
  pivot_longer(cols = -Tributary,
               names_to = "Up_Down",
               values_to = "n_Species") |> 
  ggplot(aes(x = Tributary,
             y = n_Species,
             fill = Up_Down,
             group = Up_Down)) +
  geom_bar(stat = "identity",
           position = position_dodge(width = 0.9))
EF_bar

Bar plot

Bar plot refinements

  • ggplots are additive, so we can “add” to an existing plot.
  • Change axis limits (but see Ethics in visualization)
  • Two ways to change axis labels
EF_bar +
  scale_y_continuous(limits = c(0, 50),
                     breaks = seq(0, 50, by = 5)) +
  scale_x_discrete(name = "Upstream/Downstream") +
  labs(y = "Number of Species",
       title = "Species Diversity in the Amazon")

Bar plot refinements

Scatter plot

What is the relationship between upstream and downstream diversity?

ggplot(EF, aes(x = n_Upstream,
               y = n_Downstream)) +
  geom_point()

Scatter plot

Scatter plot refinements

  • Add a straight line with a slope of 1
  • Change the color and size of all points
ggplot(EF, aes(x = n_Upstream,
               y = n_Downstream)) +
  geom_abline(slope = 1, intercept = 0, linetype = "dotted") +
  geom_point(color = "tomato", size = 3)

Scatter plot refinements

Changing aspect ratio of the axes

  • Make the plot square (coord_equal)
  • Set the axis ranges to be equal (xlim, ylim)
ggplot(EF, aes(x = n_Upstream,
               y = n_Downstream)) +
  geom_abline(slope = 1, intercept = 0, linetype = "dotted") +
  geom_point(color = "tomato", size = 3) +
  coord_equal(xlim = c(0, 30), ylim = c(0, 30))

Changing aspect ratio of the axes

scale_color_ and scale_fill_

  • Set the fill manually
  • Include a line break in the legend title string with \n
EF_bar +
  scale_fill_manual(values = c("orange", "darkgreen"),
                    name = "Upstream /\nDownstream")

scale_color_ and scale_fill_

Automated color and fill scales

EF_bar +
  scale_fill_brewer(type = "qual")

Automated color and fill scales

scale_shape_

scale_size_

EF_size <- EF |> 
  pivot_longer(cols = -Tributary,
               names_to = "Up_Down",
               values_to = "n_Species") |> 
  ggplot(aes(x = Tributary,
             y = Up_Down,
             label = n_Species,
             size = n_Species)) +
  geom_point(alpha = 0.25) +
  geom_text() +
  scale_size(range = c(1, 10))
EF_size

scale_size_

theme() changes aspects of plots

Changing axis components

EF_bar +
  labs(x = "Stream") +
  scale_fill_manual(values = c("darkred", "navy"),
                    name = "Location",
                    labels = c("Downstream", "Upstream")) +
  theme(axis.text = element_text(size = 9),
        axis.text.x = element_text(angle = 90, vjust = 0.5, hjust = 1),
        axis.title.y = element_text(face = "bold"),
        axis.title.x = element_blank(),
        legend.title = element_text(size = 10, face = "italic"),
        legend.text = element_text(size = 9))

Changing axis components

(Re)moving and reshaping the legend

  • Remove the legend
EF_size +
  theme(legend.position = "none")

Customizing the legend

ggplot(EF, aes(x = n_Upstream,
               y = n_Downstream,
               color = Tributary)) +
  geom_abline(slope = 1, intercept = 0, linetype = "dotted") +
  geom_point(size = 5) +
  scale_color_viridis_d(guide = guide_legend(ncol = 3,
                                             override.aes = list(size = 2))) +
  coord_equal(xlim = c(0, 30), ylim = c(0, 30)) +
  labs(x = "Upstream Species",
       y = "Downstream Species",
       title = "Species Diversity in the Amazon") +
  theme(legend.title = element_text(size = 10),
        legend.text = element_text(size = 9),
        legend.position = c(0.35, 0.175),
        legend.box.background = element_rect(color = "black", linewidth = 1),
        legend.box.margin = margin(4, 4, 4, 4),
        axis.title = element_text(face = "bold"))

Customizing the legend

Using element_blank() to remove plot elements

  • Remove the x-axis completely
  • Remove the space between the labels and bars
EF_bar +
  scale_y_continuous(expand = c(0, 0)) +
  theme(axis.ticks.x = element_blank(),
        axis.line.x = element_blank())

Using element_blank() to remove plot elements